﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initSomeThing();
    //这里tableview的槽函数不够  借助QItemSelectionModel 对应信号函数和槽函数参数要对应
    connect(m_select_model, &QItemSelectionModel::currentChanged, this, &MainWindow::do_currentChanged);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//做相关的启动初始化 比如模型的声明，以及相关必要成员的声明
void MainWindow::initSomeThing()
{
    m_model = new QStandardItemModel(2, 6, this); //声明数据模型 行 列 父定义
    m_select_model = new QItemSelectionModel(m_model, this); //选择模型建立在数据模型之上

    //设置数据模型  设置选择模型  设置选择模式（禁止，一项，多项，按键配合） 选择行为（项目，行，列）
    ui->m_tableView->setModel(m_model);
    ui->m_tableView->setSelectionModel(m_select_model);
    ui->m_tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    ui->m_tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
//    ui->m_tableView->setShowGrid(true);
    setCentralWidget(ui->splitter);

    //初始化必要的状态栏组件
    m_lab_file = new QLabel("当前文件：", this);
    m_lab_pos = new QLabel("当前单元格位置：",this);
    m_lab_text = new QLabel("当前单元格内容：",this);

    m_lab_file->setMinimumWidth(200);
    m_lab_pos->setMinimumWidth(200);
    m_lab_text->setMinimumWidth(300);

    m_lab_pos->setAlignment(Qt::AlignCenter);
    ui->statusbar->addWidget(m_lab_file);
    ui->statusbar->addWidget(m_lab_pos);
    ui->statusbar->addWidget(m_lab_text);
}

//打开文件 读取文件信息并显示  获取table要显示的内容
#include <QTextStream>
int MainWindow::openFileAndDisplay(const QString &filename)
{
    QFile file;
    file.setFileName(filename);

    //打开文件失败 则返回
    if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
        return -1;

    QTextStream stream(&file);
    ui->m_pte_display->clear();

    QStringList table_list;
    while(!stream.atEnd())
    {
        QString str = stream.readLine();
        //这里中文乱码的问题  要文件和打开方式一致才可以   这里只研究了文件不同的编码方式，实际可以设置！
        ui->m_pte_display->appendPlainText(str);
        table_list.append(str);
    }
    file.close();

    m_lab_file->setText("当前文件:"+filename);
    initTableModel(table_list);
    return 0;
}

//这里是真正的tablewidget借助tablemodel进行初始化
void MainWindow::initTableModel(QStringList &list)
{
    //设置行数  设置头部  设置实际内容
    int row_count = list.count();
    m_model->setRowCount(row_count-1); //这里要减去一行头部

    QString header = list.at(0);
    QStringList header_list = header.split(QRegularExpression("\\s+"),Qt::SkipEmptyParts);
    m_model->setHorizontalHeaderLabels(header_list);

    //设置每一个数据
    QStandardItem *aItem;
    int j=0;
    for(int i=1; i<row_count; i++)
    {
        QString temp = list.at(i);
        QStringList temp_list = temp.split(QRegularExpression("\\s+"),Qt::SkipEmptyParts);

        if(temp_list.count()<6)
        {
            continue;
        }

        for(j=0; j<5;j++)
        {
            aItem = new QStandardItem(temp_list.at(j));
            m_model->setItem(i-1, j, aItem);
        }

        aItem = new QStandardItem(header_list.at(j));
        aItem->setCheckable(true);
        aItem->setBackground(QBrush(Qt::yellow));
        if(temp_list.at(j) == "0")
        {
            aItem->setCheckState(Qt::Unchecked);
        }else
        {
            aItem->setCheckState(Qt::Checked);
        }

        m_model->setItem(i-1, j, aItem);
    }
    ui->m_tableView->resizeRowsToContents();
    for(int i=0; i<6; i++)
        ui->m_tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}

//需要借助数据模型和选择模型  实现对Qtableview进行初始化

//打开文件 读取特定格式的内容,显示在日志区  处理显示在tableview中
#include <QFileDialog>
void MainWindow::on_m_action_Openfile_triggered()
{
    QString dir_name = QApplication::applicationDirPath();
    //多个规则同时之间用空格分开   过滤规则，每个规则之间用;;分开
    QString file_name = QFileDialog::getOpenFileName(this, "选择模型文件", dir_name, "数据文件(*.txt);;所有文件(*.*)");
    if(file_name.isEmpty()) return;

    openFileAndDisplay(file_name);
}

//数据预览 获取表格数据显示在
void MainWindow::on_m_action_modeldata_triggered()
{
    ui->m_pte_display->clear();

    //获取表头  先进行显示
    QString temp_str;
    QStandardItem *aItem; //实际上对项的处理都要用到QStandardItem

    for(int i=0; i<m_model->columnCount(); i++)//按列遍历取头部
    {
        aItem = m_model->horizontalHeaderItem(i); //取水平对应头部信息。
        temp_str = temp_str+aItem->text()+"\t";
    }
    ui->m_pte_display->appendPlainText(temp_str);

    //依次把每个项进行上传
    for(int i=0; i<m_model->rowCount(); i++)
    {
        temp_str = "";
        for(int j=0; j<m_model->columnCount()-1; j++)
        {
            aItem = m_model->item(i, j);
            temp_str = temp_str+aItem->text()+QString::asprintf("\t");
        }

        //最后一行比较特殊，需要单独处理
        aItem = m_model->item(i, 5);
        if(aItem->checkState() == Qt::Checked)
        {
            temp_str += "1";
        }else
        {
            temp_str += "0";
        }
        ui->m_pte_display->appendPlainText(temp_str);
    }

}

//数据添加
void MainWindow::on_m_action_add_triggered()
{
    //借助 QStandardItem 不一个个遍历进行插入，就构造list
    QList<QStandardItem*> list_item;
    QStandardItem *aItem;
    for(int i=0; i<6-1;i++)//最后一列特殊处理
    {
        aItem = new QStandardItem(QString::number(i));
        list_item<<aItem;
    }

    //构造最后一列  columnCount()获取列数  Qt::Horizontal水平表头 Qt::DisplayRole用于视图做文本显示值用
    QString str = m_model->headerData(m_model->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    aItem = new QStandardItem(str);
    aItem->setCheckable(true);
    list_item<<aItem;

    //在最后一行插入
//    m_model->appendRow(list_item);
    m_model->insertRow(m_model->rowCount(), list_item);

    //设置选中当前项 第一项
    QModelIndex index = m_model->index(m_model->rowCount()-1, 0);
    m_select_model->clearSelection();
    m_select_model->setCurrentIndex(index, QItemSelectionModel::Select);
}

//数据插入 获取当前索引
void MainWindow::on_m_action_insert_triggered()
{
    QList<QStandardItem*> list_item;
    QStandardItem *aItem;
    for(int i=0; i<6-1;i++)//最后一列特殊处理
    {
        aItem = new QStandardItem(QString::number(i));
        list_item<<aItem;
    }

    //构造最后一列  columnCount()获取列数  Qt::Horizontal水平表头 Qt::DisplayRole用于视图做文本显示值用
    QString str = m_model->headerData(m_model->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    aItem = new QStandardItem(str);
    aItem->setCheckable(true);
    list_item<<aItem;

    QModelIndex index = m_select_model->currentIndex();
    m_model->insertRow(index.row(), list_item);
    m_select_model->clearSelection();
    m_select_model->setCurrentIndex(index, QItemSelectionModel::Select);

}

//删除行 获取选中的行 删除并确定当前选中项
void MainWindow::on_m_action_delOne_triggered()
{
    QModelIndex index = m_select_model->currentIndex();

    if(index.row() == m_model->rowCount()-1)
    {
        m_model->removeRow(index.row());
    }else //不是最后一行 先删除在确定选中
    {
        m_model->removeRow(index.row());
        m_select_model->setCurrentIndex(index, QItemSelectionModel::Select);
    }
}

void MainWindow::on_m_action_Alignleft_triggered()
{
    if(!m_select_model->hasSelection())
    {
        return;
    }

    QModelIndexList index_list = m_select_model->selectedIndexes();
    for(int i=0; i<index_list.count(); i++)
    {
        //遍历所有选中的模型
        QModelIndex aIndex = index_list.at(i);
        QStandardItem* aItem = m_model->itemFromIndex(aIndex); //通过index获取到Item
        aItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    }
}

//水平的英文是 "horizontal"。  垂直的英文是 "vertical"。
void MainWindow::on_m_action_Aligncenter_triggered()
{
    if(!m_select_model->hasSelection())
    {
        return;
    }

    QModelIndexList index_list = m_select_model->selectedIndexes();
    for(int i=0; i<index_list.count(); i++)
    {
        //遍历所有选中的模型
        QModelIndex aIndex = index_list.at(i);
        QStandardItem* aItem = m_model->itemFromIndex(aIndex); //通过index获取到Item
        aItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    }
}

void MainWindow::on_m_action_Alignright_triggered()
{
    if(!m_select_model->hasSelection())
    {
        return;
    }

    QModelIndexList index_list = m_select_model->selectedIndexes();
    for(int i=0; i<index_list.count(); i++)
    {
        //遍历所有选中的模型
        QModelIndex aIndex = index_list.at(i);
        QStandardItem* aItem = m_model->itemFromIndex(aIndex); //通过index获取到Item
        aItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
    }
}

void MainWindow::on_m_action_bold_triggered()
{
    if(!m_select_model->hasSelection())
    {
        return;
    }

    QModelIndexList index_list = m_select_model->selectedIndexes();
    for(int i=0; i<index_list.count(); i++)
    {
        //遍历所有选中的模型
        QModelIndex aIndex = index_list.at(i);
        QStandardItem* aItem = m_model->itemFromIndex(aIndex); //通过index获取到Item
        QFont font = aItem->font();
        font.setBold(true);
        aItem->setFont(font);
    }
}

//执行程序的退出，实际上绑定对应的槽函数就好
void MainWindow::on_m_action_quit_triggered()
{
    QCoreApplication::quit();
}

void MainWindow::do_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    Q_UNUSED(previous);
    if(!current.isValid())
        return;
    //获取选中的行和列号  以及内容
    QString num_str = QString::asprintf("当前单元格：%d行，%d列",current.row(), current.column());
    QString data_str = "单元格内容："+m_model->itemFromIndex(current)->text();
    m_lab_pos->setText(num_str);
    m_lab_text->setText(data_str);
}

/****   保存 另存为
void MainWindow::on_actSave_triggered()
{ //保存为文件
    QString curPath=QCoreApplication::applicationDirPath(); //获取应用程序的路径
//调用打开文件对话框选择一个文件
    QString aFileName=QFileDialog::getSaveFileName(this,tr("选择一个文件"),curPath,
                 "井斜数据文件(*.txt);;所有文件(*.*)");

if (aFileName.isEmpty()) //未选择文件，退出
    return;

QFile aFile(aFileName);
if (!(aFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)))
    return; //以读写、覆盖原有内容方式打开文件

QTextStream aStream(&aFile); //用文本流读取文件

QStandardItem   *aItem;
int i,j;
QString str;

ui->plainTextEdit->clear();

//获取表头文字
for (i=0;i<m_model->columnCount();i++)
{
    aItem=m_model->horizontalHeaderItem(i); //获取表头的项数据
    str=str+aItem->text()+"\t\t";  //以TAB见隔开
}
aStream<<str<<"\n";  //文件里需要加入换行符 \n
ui->plainTextEdit->appendPlainText(str);

//获取数据区文字
for ( i=0;i<m_model->rowCount();i++)
{
    str="";
    for( j=0;j<m_model->columnCount()-1;j++)
    {
        aItem=m_model->item(i,j);
        str=str+aItem->text()+QString::asprintf("\t\t");
    }

    aItem=m_model->item(i,j); //最后一列是逻辑型
    if (aItem->checkState()==Qt::Checked)
        str=str+"1";
    else
        str=str+"0";

    ui->plainTextEdit->appendPlainText(str);
    aStream<<str<<"\n";
}
}
****/
